/*
 * OPIAM Suite
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */

package opiam.admin.faare.config;

import opiam.admin.faare.config.javabeans.JBExports;

import org.apache.commons.digester.Digester;

import org.apache.log4j.Logger;

import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import java.io.IOException;
import java.io.InputStream;


/**
 * Export service configuration loading from the XML file.
 *
 * The XML file must contain the following lines :
 * <!DOCTYPE mapping PUBLIC
 *         "-//OPIAM ADMIN//DTD Export Service Configuration 1.0//EN"
 *         "http://www.opiam.org/admin/dtd/exports_conf.dtd">
 *
 * The second line is registered to the digester (it does not need to be an actual URL).
 *
 */
public final class ExportsConfig implements ErrorHandler
{
    /** Log4J. */
    private static Logger _logger = Logger.getLogger(ExportsConfig.class.getName());

    /** DOCTYPE key. */
    public static final String EXPORT_CONFIG_DTD_KEY = "-//OPIAM ADMIN//DTD ACL Service Configuration 1.0//EN";

    /** DOCTYPE URL. */
    public static final String EXPORT_CONFIG_DTD_URL = "/config/service/exports/exports_conf.dtd";

    /** XML Parser. */
    private static Digester _digester = null;

    /** Current instance. */
    private static ExportsConfig _instance = null;

    /** Parser exception. */
    private static SAXParseException _saxParseException = null;

    /**
     * Constructor for ProfilesDigester.
     */
    private ExportsConfig()
    {
        super();
    }

    /**
     * Digester initialization with DTD fields.
     */
    private static void initProfileDigester()
    {
        _saxParseException = null;
        _digester = new Digester();

        _digester.setErrorHandler(_instance);
        _digester.setValidating(true);

        _logger.debug("initProfileDigester EXPORT_CONFIG_DTD_KEY : " +
            EXPORT_CONFIG_DTD_KEY);
        _logger.debug(
            "initProfileDigester ExportsConfig.class.getResource(EXPORT_CONFIG_DTD_URL).toString() : " +
            ExportsConfig.class.getResource(EXPORT_CONFIG_DTD_URL).toString());

        _digester.register(EXPORT_CONFIG_DTD_KEY,
            ExportsConfig.class.getResource(EXPORT_CONFIG_DTD_URL).toString());

        _digester.addObjectCreate("exports",
            "opiam.admin.faare.config.javabeans.JBExports");

        /* Export */
        _digester.addObjectCreate("exports/export",
            "opiam.admin.faare.config.javabeans.JBExport");
        _digester.addSetNext("exports/export", "addExport",
            "opiam.admin.faare.config.javabeans.JBExport");
        _digester.addSetProperties("exports/export");

        _digester.addObjectCreate("exports/export/quotes",
                "opiam.admin.faare.config.javabeans.JBQuotes");
        _digester.addSetNext("exports/export/quotes", "setQuoter",
                "opiam.admin.faare.config.javabeans.JBQuotes");
        _digester.addSetProperties("exports/export/quotes");
        _digester.addObjectCreate("exports/export/quotes/char",
                "opiam.admin.faare.config.javabeans.JBValueElement");
        _digester.addSetNext("exports/export/quotes/char", "addSpechars",
                "opiam.admin.faare.config.javabeans.JBValueElement");
        _digester.addSetProperties("exports/export/quotes/char");

        _digester.addObjectCreate("exports/export/attribute",
                "opiam.admin.faare.config.javabeans.JBAttribute");
        _digester.addSetNext("exports/export/attribute", "addElementsList",
                "opiam.admin.faare.config.javabeans.JBAttribute");
        _digester.addSetProperties("exports/export/attribute");
        _digester.addObjectCreate("exports/export/text",
                "opiam.admin.faare.config.javabeans.JBValueElement");
        _digester.addSetNext("exports/export/text", "addElementsList",
                "opiam.admin.faare.config.javabeans.JBValueElement");
        _digester.addSetProperties("exports/export/text");

        /* Profile */
        _digester.addObjectCreate("exports/profile",
            "opiam.admin.faare.config.javabeans.JBExportProfile");
        _digester.addSetNext("exports/profile", "addExportProfile",
            "opiam.admin.faare.config.javabeans.JBExportProfile");
        _digester.addSetProperties("exports/profile");

        _digester.addObjectCreate("exports/profile/export",
            "opiam.admin.faare.config.javabeans.JBExport");
        _digester.addSetNext("exports/profile/export", "addExport",
            "opiam.admin.faare.config.javabeans.JBExport");
        _digester.addSetProperties("exports/profile/export");

        _digester.addObjectCreate("exports/profile/export/quotes",
                "opiam.admin.faare.config.javabeans.JBQuotes");
        _digester.addSetNext("exports/profile/export/quotes", "setQuoter",
                "opiam.admin.faare.config.javabeans.JBQuotes");
        _digester.addSetProperties("exports/profile/export/quotes");
        _digester.addObjectCreate("exports/profile/export/quotes/char",
                "opiam.admin.faare.config.javabeans.JBValueElement");
        _digester.addSetNext("exports/profile/export/quotes/char", "addSpechars",
                "opiam.admin.faare.config.javabeans.JBValueElement");
        _digester.addSetProperties("exports/profile/export/quotes/char");

        _digester.addObjectCreate("exports/profile/export/attribute",
                "opiam.admin.faare.config.javabeans.JBAttribute");
        _digester.addSetNext("exports/profile/export/attribute", "addElementsList",
                "opiam.admin.faare.config.javabeans.JBAttribute");
        _digester.addSetProperties("exports/profile/export/attribute");
        _digester.addObjectCreate("exports/profile/export/text",
                "opiam.admin.faare.config.javabeans.JBValueElement");
        _digester.addSetNext("exports/profile/export/text", "addElementsList",
                "opiam.admin.faare.config.javabeans.JBValueElement");
        _digester.addSetProperties("exports/profile/export/text");

    }

    /**
     * Gets ExportsConfig instance.
     *
     * @return ExportsConfig instance.
     */
    public static ExportsConfig getInstance()
    {
        if (_instance == null)
        {
            _instance = new ExportsConfig();
            initProfileDigester();
        }

        return _instance;
    }

    /**
     * Gets exports config.
     *
     * @param in  Configuration stream.
     *
     * @return The exports config.
     *
     * @throws IOException exception while reading stream.
     * @throws SAXException exception while parsing data.
     */
    public JBExports readConfig(InputStream in)
        throws IOException, SAXException
    {
        JBExports result = null;
        result = (JBExports) _digester.parse(in);

        if (_saxParseException != null)
        {
            _logger.debug("Exception : " + _saxParseException.getMessage());
            throw new SAXException(_saxParseException.getMessage());
        }

        result.enrichProfileExports();

        return result;
    }

    /**
     * Parsing error callback.
     *
     * @param saxParseException  Parsing exception.
     */
    @Override
	public void error(SAXParseException saxParseException)
    {
        _logger.debug(" error exception!!!!!!!!!!!!!!!");
        _saxParseException = saxParseException;
    }

    /**
     * Parsing fatal error callback.
     *
     * @param saxParseException  Parsing exception.
     */
    @Override
	public void fatalError(SAXParseException saxParseException)
    {
        _logger.debug("fatalError exception!!!!!!!!!!!!!!!");
        _saxParseException = saxParseException;
    }

    /**
     * Parsing warning callback.
     *
     * @param saxParseException  Parsing exception.
     */
    @Override
	public void warning(SAXParseException saxParseException)
    {
        _logger.debug("warning : " + saxParseException.getMessage());
    }
}
